package cn.kow.kmall.service.impl;

import cn.kow.kmall.core.constant.KmallStatusConstant;
import cn.kow.kmall.dao.CartItemRepository;
import cn.kow.kmall.pojo.dto.CartItemDTO;
import cn.kow.kmall.pojo.dto.CartItemUpdateDTO;
import cn.kow.kmall.pojo.entity.CartItem;
import cn.kow.kmall.service.CartService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import java.util.ArrayList;
import java.util.List;

/**
 *
 * @author lijun
 */
@Service("cartService")
public class CartServiceImpl implements CartService {

    @Autowired
    private CartItemRepository cartItemRepository;

    @Override
    public List<CartItem> listItem(Long uid) {
        CartItem record = new CartItem();
        record.setUid(uid);
        record.setStatus(KmallStatusConstant.NORMAL);
        return cartItemRepository.listAll(record);
    }

    @Override
    public void saveItem(CartItemDTO itemDTO) {
        Long uid = itemDTO.getUid();
        Long skuId = itemDTO.getSkuId();
        Integer num = itemDTO.getItemNum();
        Boolean checked = itemDTO.getChecked();
        CartItem cartItem = getByUidAndSkuId(uid, skuId);
        if (cartItem != null) {
            cartItem.setItemNum(num + cartItem.getItemNum());
            cartItem.setChecked(checked);
            cartItemRepository.update(cartItem);
        } else {
            cartItem = new CartItem();
            cartItem.setUid(uid);
            cartItem.setItemId(itemDTO.getItemId());
            cartItem.setSkuId(itemDTO.getSkuId());
            cartItem.setItemName(itemDTO.getItemName());
            cartItem.setItemNum(itemDTO.getItemNum());
            cartItem.setItemPic(itemDTO.getItemPic());
            cartItem.setItemSpec(itemDTO.getItemSpec());
            cartItem.setSellingPrice(itemDTO.getSellingPrice());
            cartItem.setMarketPrice(itemDTO.getMarketPrice());
            cartItem.setChecked(itemDTO.getChecked());
            cartItemRepository.create(cartItem);
        }
    }

    @Override
    public void updateItem(CartItemUpdateDTO itemDTO) {
        Long uid = itemDTO.getUid();
        Long skuId = itemDTO.getSkuId();
        Integer num = itemDTO.getItemNum();
        Boolean checked = itemDTO.getChecked();
        CartItem cartItem = getByUidAndSkuId(uid, skuId);
        if (null == cartItem) {
            return;
        }
        cartItem.setItemNum(num);
        cartItem.setChecked(checked);
        cartItemRepository.update(cartItem);
    }

    @Override
    public void deleteItem(Long uid, List<Long> skuIdList) {
        List<CartItem> list = cartItemRepository.findAll(new Specification<CartItem>() {
            @Override
            public Predicate toPredicate(Root root, CriteriaQuery criteriaQuery, CriteriaBuilder criteriaBuilder) {
                List<Predicate> predicates = new ArrayList<>();
                predicates.add(root.get("skuId").in(skuIdList));
                predicates.add(criteriaBuilder.equal(root.get("uid"), uid));
                predicates.add(criteriaBuilder.equal(root.get("deleted"), false));
                predicates.add(criteriaBuilder.equal(root.get("status"), KmallStatusConstant.NORMAL));
                return criteriaBuilder.and(predicates.toArray(new Predicate[predicates.size()]));
            }
        });
        cartItemRepository.deleteAll(list);
    }

    @Override
    public void updateCheck(Long uid, Boolean checked) {
        List<CartItem> itemList = this.listItem(uid);
        List<CartItem> updateList = new ArrayList<>();
        for (CartItem cartItem : itemList) {
            if (!cartItem.getChecked().equals(checked)) {
                cartItem.setChecked(checked);
                updateList.add(cartItem);
            }
        }
        cartItemRepository.saveAll(updateList);
    }

    public CartItem getByUidAndSkuId(Long uid, Long skuId) {
        CartItem record = new CartItem();
        record.setUid(uid);
        record.setSkuId(skuId);
        record.setStatus(KmallStatusConstant.NORMAL);
        return cartItemRepository.getOne(record);
    }
}
